package cn.remex.db;

import cn.remex.core.Rvo;
import cn.remex.core.util.Assert;
import cn.remex.db.appbeans.BeanVo;
import cn.remex.db.appbeans.MapVo;
import cn.remex.db.lambdaapi.ColumnPredicate;
import cn.remex.db.rsql.model.Modelable;
import cn.remex.db.sql.AggregateFunction;

import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.function.Function;
import java.util.function.Predicate;

public abstract class DbRvo<T extends Modelable> implements Rvo {

	//对结果进行判断的
	public DbRvo<T> assertTrue(Predicate<DbRvo<T>> predicate, String errorCode, String errorMsg) {
		Assert.isTrue(predicate.test(this),errorCode,errorMsg);
		return this;
	}
	public DbRvo<T> assertEffectOneRow(String errorCode, String errorMsg) {
		return this.assertTrue(rvo -> rvo.getEffectRowCount() == 1, errorCode, errorMsg);
	}

	/**
	 * 
	 */
	private static final long serialVersionUID = 2873012626158632379L;
	private StringBuilder msg = new StringBuilder();
	private boolean status;

	public void setStatus(boolean status) {
		this.status = status;
	}
	public void setMsg(final boolean status, final String msg) {
		this.status = status;
		this.msg.append(msg);
	}
	public abstract Object getCell(int rowNO, int columnNO);
	public abstract Object getCell(int rowNO, ColumnPredicate<T> cp, AggregateFunction aggregateFunction);
	public abstract Object getCell(int rowIndex, String needColumnName);
	public abstract Object getCell(int rowIndex, ColumnPredicate<T> cp);
	public abstract List<Object> getCells(int columnIndex, String columnValue, int needColumnIndex);
	public abstract List<Object> getCells(int columnIndex, String columnValue, String needColumnName);
	public abstract List<Object> getCells(String columnName, String columnValue, int needColumnIndex);
	public abstract List<Object> getCells(String columnName, String columnValue, String needColumnName);
	public abstract List<Object> getCells(final ColumnPredicate<T> cp, final String columnValue, final ColumnPredicate<T> needColumnNameCp, AggregateFunction aggregateFunction);
	public abstract Object getCell(final ColumnPredicate<T> columnCp, final String columnValue, final ColumnPredicate<T> needColumnNameCp, AggregateFunction aggregateFunction);
	public abstract List<Object> getColumn(int index);
	public abstract List<T> getColumn(int index, Class<T> clazz);
	public abstract List<Object> getColumn(String needColumnName);
	public abstract int getEffectRowCount();
	public abstract List<?> getGridData();
	public abstract String getId();
	public abstract TreeMap<String, String> getMapFromColumns(String keyColumn, String valueColumn);
	public abstract TreeMap<String, String> getMapFromColumns(ColumnPredicate<T> keyCp, ColumnPredicate<T> valueCp, AggregateFunction valueAggregateFunction);
	public abstract TreeMap<String, String> getMapFromColumns(String keyColumn, String valueColumn, String restrainColumn, String restrainValue);
	public abstract List<Map<String, Object>> getMapRows();
	public abstract List<Map<String, Object>> getMapTree();

	/* 设置返回消息	 */
	@Override
	public String getMsg() {
		return this.msg.toString();
	}
	public StringBuilder appendMsg(final String msg) {
		this.msg.append(msg);
		return this.msg;
	}
	public abstract int getPagination();
	public abstract int getRecordCount();
	public abstract int getRecords();
	public abstract int getRowCount();
	public abstract List<List<Object>> getRows();
	public abstract List<List<Object>> getRows(int columnIndex, String columnValue);
	public abstract List<List<Object>> getRows(String columnName, String columnValue);
	/* 设置数据状态	 */
	@Override
	public boolean getStatus() {
		return this.status;
	}
	public abstract int getTitleIndex(String columnName);
	public abstract List<String> getTitles();
	public abstract Map<String, String> getUserData();
	/*
	 * 将查询结果的第一条记录复制给bean
	 */
	public abstract void assignRow(T bean);
	public abstract T obtainBean();
	public abstract List<T> obtainBeans();
	public abstract <M extends Modelable> List<M> obtainBeans(Class<M> modelClass);
	public abstract List<?> obtainObjects();
	public abstract <C> List<C> obtainObjects(final Class<C> clazz);
	public abstract Map<String, String> obtainMap(final String keyColumn, final String valueColumn);
	public abstract Map<String, String> obtainMap(String keyColumn, String valueColumn, String restrainColumn, String restrainValue);
	public abstract Map<String, T> obtainObjectsMap(final String columnName, final Class<T> clazz);
	public abstract Map<String, T> obtainObjectsMap(final String columnName);
	public abstract BeanVo<T> obtainBeanVo(Class<T> clazz);
	public abstract MapVo obtainMapVo();
	public abstract Class<T> getBeanClass();

	public abstract DbRvo<T> translateColumnValue(final ColumnPredicate<T> cp, Object... args);
	public abstract DbRvo<T> translateColumnValue(final ColumnPredicate<T> cp, Function<Object, Object> translateFunc);
	public abstract DbRvo<T> translateColumnValue(final String columnName, Object... args);
	public abstract DbRvo<T> translateColumnValue(final String columnName, Function<Object, Object> translateFunc);
}
